﻿using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.DB;
using YArchitech.LIB;
using YArchitech.Revit;
using YJKRGeometry;

namespace HYOpeningDetail
{
	internal class CenterBasedRectComponent : RectangleComponent
	{
		public void DimRectangularFunction(ElementInfo dicElementInfo, FamilyInstance famiPumb, List<XYZ> lstBoxVertexes, ViewPlan viewPlan, Dictionary<XYZ, DataWall> dicWallCurve, Dictionary<XYZ, List<Curve>> dicCombineGridCurve, List<Document> lstDoc, int iBoxCategory)
		{
			this.m_doc = lstDoc[0];
			this.m_lstDoc = lstDoc;
			Transaction transaction = new Transaction(this.m_doc, "Dim");
			try
			{
				transaction.Start();
				if (OpeningViewDataSetForm.BRadSelGrid)
				{
					this.CreateLocationDimensionByGridCurve(dicElementInfo, lstBoxVertexes, viewPlan, dicCombineGridCurve);
				}
				else
				{
					this.CreateLocationDimensionByWallCurve(dicElementInfo, lstBoxVertexes, viewPlan, dicWallCurve);
				}
				this.CreateLeaderDimension(dicElementInfo, famiPumb, lstBoxVertexes, viewPlan, iBoxCategory);
				transaction.Commit();
			}
			catch (Exception)
			{
				transaction.RollBack();
			}
		}

		private void CreateLeaderDimension(ElementInfo dicElementInfo, FamilyInstance famiPumb, List<XYZ> lstBoxVertexes, ViewPlan viewPlan, int iBoxCategory)
		{
			string strLevelText = null;
			string strFamText = null;
			this.GetDimText(dicElementInfo, famiPumb, iBoxCategory, viewPlan, ref strLevelText, ref strFamText);
			lstBoxVertexes = (from pt in lstBoxVertexes
			orderby pt.Y
			select pt).ToList<XYZ>();
			XYZ xyz = lstBoxVertexes[0].Add(lstBoxVertexes[1]).Divide(2.0);
			XYZ ptDimPosionFir = new XYZ(xyz.X + NumbericTools.mmToFeet(800.0), xyz.Y - NumbericTools.mmToFeet(400.0), xyz.Z);
			base.LeaderDimension(xyz, ptDimPosionFir, strFamText, strLevelText, viewPlan);
		}

		private bool CreateLocationDimensionByWallCurve(ElementInfo dicElementInfo, List<XYZ> lstBoxVertexes, ViewPlan viewPlan, Dictionary<XYZ, DataWall> dicWallCurve)
		{
			XYZ ptFamInstance = null;
			LocationPoint locationPoint = dicElementInfo.element.Location as LocationPoint;
			if (dicElementInfo.revitLink != null)
			{
				Transform transform = dicElementInfo.revitLink.GetTransform();
				ptFamInstance = transform.OfPoint(locationPoint.Point);
			}
			else
			{
				ptFamInstance = locationPoint.Point;
			}
			dicWallCurve = (from k in dicWallCurve
			orderby k.Key.DistanceTo(ptFamInstance)
			select k).ToDictionary((KeyValuePair<XYZ, DataWall> k) => k.Key, (KeyValuePair<XYZ, DataWall> k) => k.Value);
			if (dicWallCurve.Count > 0)
			{
				DataWall value = dicWallCurve.ElementAt(0).Value;
				XYZ key = dicWallCurve.ElementAt(0).Key;
				List<XYZ> lstNewBoxVertexes = new List<XYZ>();
				lstBoxVertexes.ForEach(delegate(XYZ i)
				{
					lstNewBoxVertexes.Add(i);
				});
				lstNewBoxVertexes.Add(lstBoxVertexes[0]);
				List<Line> list = new List<Line>();
				List<XYZ> list2 = new List<XYZ>();
				for (int j = 0; j < lstNewBoxVertexes.Count - 1; j++)
				{
					XYZ xyz = new XYZ(lstNewBoxVertexes[j].X, lstNewBoxVertexes[j].Y, key.Z);
					XYZ xyz2 = new XYZ(lstNewBoxVertexes[j + 1].X, lstNewBoxVertexes[j + 1].Y, key.Z);
					Line item = Line.CreateBound(xyz, xyz2);
					list.Add(item);
					if (j < lstBoxVertexes.Count)
					{
						list2.Add(xyz);
					}
				}
				Line line = value.curvrFirst as Line;
				Line line2 = value.curveSecond as Line;
				double dFirstWallWidth = value.dFirstWallWidth;
				double dSecondWallWidth = value.dSecondWallWidth;
				this.CreateDimensionByWallCurve(line, line2, dFirstWallWidth, dSecondWallWidth, key, list, viewPlan);
				this.CreateDimensionByWallCurve(line2, line, dSecondWallWidth, dFirstWallWidth, key, list, viewPlan);
				return true;
			}
			return false;
		}

		private bool CreateLocationDimensionByGridCurve(ElementInfo dicElementInfo, List<XYZ> lstBoxVertexes, ViewPlan viewPlan, Dictionary<XYZ, List<Curve>> dicCombineGridCurve)
		{
			XYZ ptFamInstance = null;
			LocationPoint locationPoint = dicElementInfo.element.Location as LocationPoint;
			if (dicElementInfo.revitLink != null)
			{
				Transform transform = dicElementInfo.revitLink.GetTransform();
				ptFamInstance = transform.OfPoint(locationPoint.Point);
			}
			else
			{
				ptFamInstance = locationPoint.Point;
			}
			XYZ ptGridIntersect = null;
			List<Curve> list = null;
			dicCombineGridCurve = (from k in dicCombineGridCurve
			orderby k.Key.DistanceTo(ptFamInstance)
			select k).ToDictionary((KeyValuePair<XYZ, List<Curve>> k) => k.Key, (KeyValuePair<XYZ, List<Curve>> k) => k.Value);
			if (dicCombineGridCurve.Count > 0)
			{
				ptGridIntersect = dicCombineGridCurve.ElementAt(0).Key;
				list = dicCombineGridCurve.ElementAt(0).Value;
				List<XYZ> lstNewBoxVertexes = new List<XYZ>();
				lstBoxVertexes.ForEach(delegate(XYZ i)
				{
					lstNewBoxVertexes.Add(i);
				});
				lstBoxVertexes.Add(lstBoxVertexes[0]);
				List<Line> list2 = new List<Line>();
				List<XYZ> list3 = new List<XYZ>();
				for (int j = 0; j < lstBoxVertexes.Count - 1; j++)
				{
					XYZ xyz = new XYZ(lstBoxVertexes[j].X, lstBoxVertexes[j].Y, ptGridIntersect.Z);
					XYZ xyz2 = new XYZ(lstBoxVertexes[j + 1].X, lstBoxVertexes[j + 1].Y, ptGridIntersect.Z);
					Line item = Line.CreateBound(xyz, xyz2);
					list2.Add(item);
					if (j < lstBoxVertexes.Count)
					{
						list3.Add(xyz);
					}
				}
				new XYZ(ptFamInstance.X, ptFamInstance.Y, ptGridIntersect.Z);
				List<XYZ> list4 = new List<XYZ>();
				List<Line> list5 = new List<Line>();
				foreach (Line line in list2)
				{
					foreach (Curve curve in list)
					{
						XYZ xyz3 = new YJKLine(curve as Line).IntersectionPoint(line);
						if (xyz3 != null)
						{
							list4.Add(xyz3);
							list5.Add(line);
						}
					}
				}
				if (list4.Count == 0)
				{
					list3 = (from pt in list3
					orderby pt.DistanceTo(ptGridIntersect)
					select pt).ToList<XYZ>();
					XYZ xyz4 = list3[0];
					List<XYZ> list6 = new List<XYZ>();
					foreach (Curve curve2 in list)
					{
						YJKLine hyline = new YJKLine(curve2 as Line);
						list6.Add(hyline.GetProject(xyz4));
					}
					XYZ vectorMove = xyz4.Subtract(list6[0]).Normalize();
					XYZ vectorMove2 = xyz4.Subtract(list6[1]).Normalize();
					Line dimNewLine = Line.CreateBound(list6[0], xyz4);
					base.CreateDetailLine(list3[1], list3[2], vectorMove2, viewPlan, dimNewLine, false);
					base.CreateDetailLine(list6[0], xyz4, vectorMove2, viewPlan, dimNewLine, false);
					Line dimNewLine2 = Line.CreateBound(list6[1], xyz4);
					base.CreateDetailLine(list3[1], xyz4, vectorMove, viewPlan, dimNewLine2, false);
					base.CreateDetailLine(list6[1], xyz4, vectorMove, viewPlan, dimNewLine2, false);
				}
				if (list4.Count == 2)
				{
					Curve grdCurve = null;
					foreach (Curve curve3 in list)
					{
						YJKLine hyline2 = new YJKLine(curve3 as Line);
						foreach (Line otherLine in list5)
						{
							if (hyline2.IsParallel(otherLine))
							{
								grdCurve = curve3;
								break;
							}
						}
					}
					list4 = (from a in list4
					orderby grdCurve.Distance(a)
					select a).ToList<XYZ>();
					list5 = (from b in list5
					orderby b.Distance(ptGridIntersect)
					select b).ToList<Line>();
					YJKLine hyline3 = new YJKLine(grdCurve as Line);
					XYZ project = hyline3.GetProject(list5[0].GetEndPoint(0));
					hyline3.GetProject(list5[0].GetEndPoint(1));
					XYZ vectorMove3 = list5[0].GetEndPoint(0).Subtract(list4[0]).Normalize();
					XYZ xyz5 = list4[0].Subtract(ptGridIntersect).Normalize();
					Line dimNewLine3 = Line.CreateBound(list5[0].GetEndPoint(0), project);
					base.CreateDetailLine(list5[0].GetEndPoint(0), project, vectorMove3, viewPlan, dimNewLine3, false);
					Line dimNewLine4 = Line.CreateBound(list5[0].GetEndPoint(0), list4[0]);
					base.CreateDetailLine(list5[0].GetEndPoint(0), list4[0], -xyz5, viewPlan, dimNewLine4, false);
					Line.CreateBound(list5[0].GetEndPoint(1), list4[0]);
					base.CreateDetailLine(list5[0].GetEndPoint(1), list4[0], -xyz5, viewPlan, dimNewLine4, false);
				}
				if (list4.Count == 4)
				{
					List<Line> list7 = new List<Line>();
					lstNewBoxVertexes = (from pt in lstNewBoxVertexes
					orderby pt.DistanceTo(ptGridIntersect)
					select pt).ToList<XYZ>();
					foreach (Line line2 in list2)
					{
						if (new YJKLine(line2).IsPointOnLine(lstNewBoxVertexes[0]))
						{
							list7.Add(line2);
						}
					}
					using (List<Line>.Enumerator enumerator = list7.GetEnumerator())
					{
						while (enumerator.MoveNext())
						{
							Line boxIntersectLine = enumerator.Current;
							list4 = (from pt in list4
							orderby boxIntersectLine.Distance(pt)
							select pt).ToList<XYZ>();
							XYZ xyz6 = ptGridIntersect.Subtract(list4[0]).Normalize();
							Line dimNewLine5 = Line.CreateBound(boxIntersectLine.GetEndPoint(0), list4[0]);
							base.CreateDetailLine(boxIntersectLine.GetEndPoint(0), list4[0], -xyz6, viewPlan, dimNewLine5, false);
							Line dimNewLine6 = Line.CreateBound(list4[0], boxIntersectLine.GetEndPoint(1));
							base.CreateDetailLine(list4[0], boxIntersectLine.GetEndPoint(1), -xyz6, viewPlan, dimNewLine6, false);
						}
					}
				}
				return true;
			}
			return false;
		}

		private void GetDimText(ElementInfo dicElementInfo, FamilyInstance famiPumb, int iBoxCategory, ViewPlan viewPlan, ref string strLevelText, ref string strFamText)
		{
			FamilyInstance familyInstance;
			if (iBoxCategory == 4)
			{
				familyInstance = (dicElementInfo.element as FamilyInstance);
			}
			else
			{
				familyInstance = famiPumb;
			}
			double value = 0.0;
			double value2 = 0.0;
			double value3 = 0.0;
			double value4 = 0.0;
			double value5 = 0.0;
			Parameter parameter = base.GetParameter(familyInstance, "长度");
			Parameter parameter2 = base.GetParameter(familyInstance, "宽度");
			Parameter parameter3 = base.GetParameter(familyInstance, "深度");
			Parameter parameter4 = base.GetParameter(familyInstance, "高度");
			Parameter parameter5 = base.GetParameter(familyInstance, "重量");
			Parameter parameter6 = base.GetParameter(familyInstance, "净重");
			if (parameter5 != null)
			{
				value5 = parameter5.AsDouble();
			}
			else if (parameter6 != null)
			{
				value5 = parameter6.AsDouble();
			}
			if (parameter != null)
			{
				value = NumbericTools.feetTomm(parameter.AsDouble());
			}
			if (parameter2 != null)
			{
				value2 = NumbericTools.feetTomm(parameter2.AsDouble());
			}
			if (parameter3 != null)
			{
				value3 = NumbericTools.feetTomm(parameter3.AsDouble());
			}
			if (parameter4 != null)
			{
				value4 = NumbericTools.feetTomm(parameter4.AsDouble());
			}
			string text = Convert.ToInt32(value).ToString();
			string text2 = Convert.ToInt32(value2).ToString();
			string text3 = Convert.ToInt32(value3).ToString();
			string text4 = Convert.ToInt32(value4).ToString();
			string str = Convert.ToInt32(value5).ToString();
			string str2 = familyInstance.Symbol.Family.Name.ToString();
			string text5 = null;
			if (iBoxCategory != 4)
			{
				text5 = famiPumb.Symbol.Family.Name.ToString();
			}
			if (iBoxCategory == 4)
			{
				strFamText = "集水坑";
				strLevelText = string.Concat(new string[]
				{
					text,
					"X",
					text2,
					"X",
					text3
				});
				return;
			}
			if (text5.Contains("水箱"))
			{
				string str3 = Convert.ToInt32(NumbericTools.feetTomm(this.GetDepthInter(dicElementInfo, famiPumb, viewPlan))).ToString();
				strFamText = str2 + "基础，高于建筑完成面" + str3 + "mm";
				strLevelText = string.Concat(new string[]
				{
					text,
					"X",
					text2,
					"X",
					text4,
					"(H)"
				});
				return;
			}
			string str4 = Convert.ToInt32(NumbericTools.feetTomm(this.GetDepthInter(dicElementInfo, famiPumb, viewPlan))).ToString();
			strFamText = str2 + "基础，高于建筑完成面" + str4 + "mm";
			strLevelText = "荷载" + str + "Kg";
		}

		private void CreateDimensionByWallCurve(Line lineFirst, Line lineSecond, double dFirstLineWidth, double dSecondLineWidth, XYZ ptWallIntersect, List<Line> lstBoxLine, ViewPlan viewPlan)
		{
			Line line = null;
			double num = 0.0;
			double val = double.MaxValue;
			foreach (Line line2 in lstBoxLine)
			{
				YJKLine hyline = new YJKLine(line2);
				if (hyline.IsParallel(lineFirst))
				{
					double distance = hyline.GetDistance(lineFirst);
					if (Geometry.GreaterThan(val, distance))
					{
						val = distance;
						line = line2;
						num = dSecondLineWidth;
					}
				}
			}
			List<XYZ> list = new List<XYZ>();
			list.Add(line.GetEndPoint(0));
			list.Add(line.GetEndPoint(1));
			YJKCurve hycurve = new YJKCurve(Line.CreateUnbound(line.GetEndPoint(0), line.Direction));
			XYZ ptFirIntersect = hycurve.IntersectionPoint(lineSecond);
			list = (from pt in list
			orderby pt.DistanceTo(ptFirIntersect)
			select pt).ToList<XYZ>();
			XYZ xyz = list[0].Subtract(ptFirIntersect).Normalize();
			XYZ vectorMove = ptFirIntersect.Subtract(ptWallIntersect).Normalize();
			XYZ xyz2 = ptFirIntersect.Add(xyz * 0.5 * num);
			Line dimNewLine = Line.CreateBound(list[0], list[1]);
			base.CreateDetailLine(list[0], list[1], vectorMove, viewPlan, dimNewLine, false);
			if (!Geometry.Lessthan_Or_Equal(list[0].DistanceTo(xyz2), NumbericTools.mmToFeet(0.8)))
			{
				Line dimNewLine2 = Line.CreateBound(list[0], xyz2);
				base.CreateDetailLine(list[0], xyz2, vectorMove, viewPlan, dimNewLine2, false);
			}
		}

		private double GetDepthInter(ElementInfo dicElementInfo, FamilyInstance famiPumb, ViewPlan viewPlan)
		{
			Transform transform = null;
			if (dicElementInfo.revitLink != null)
			{
				transform = dicElementInfo.revitLink.GetTransform();
			}
			XYZ elementTopXYZ = this.GetElementTopXYZ(dicElementInfo.element, transform);
			Element boundingFloofOrRoof = this.GetBoundingFloofOrRoof(dicElementInfo.element, viewPlan);
			if (boundingFloofOrRoof != null)
			{
				XYZ elementTopXYZ2 = this.GetElementTopXYZ(boundingFloofOrRoof, null);
				return elementTopXYZ.Z - elementTopXYZ2.Z;
			}
			return 0.0;
		}

		private XYZ GetElementTopXYZ(Element elem, Transform transform)
		{
			List<Face> list = new List<Face>();
			List<XYZ> list2 = new List<XYZ>();
			PublicFunction.GetAllFace(elem, ref list, XYZ.BasisZ, null);
			foreach (Face face in list)
			{
				PlanarFace planarFace = face as PlanarFace;
				if (planarFace != null)
				{
					if (elem is FamilyInstance)
					{
						Transform totalTransform = (elem as FamilyInstance).GetTotalTransform();
						if (totalTransform != null)
						{
							XYZ item = totalTransform.OfPoint(planarFace.Origin);
							list2.Add(item);
						}
					}
					else
					{
						list2.Add(planarFace.Origin);
					}
				}
			}
			List<XYZ> lstPtNewOrgin = new List<XYZ>();
			if (transform != null)
			{
				list2.ForEach(delegate(XYZ pt)
				{
					lstPtNewOrgin.Add(transform.OfPoint(pt));
				});
				lstPtNewOrgin = (from pt in lstPtNewOrgin
				orderby pt.Z
				select pt).ToList<XYZ>();
				return lstPtNewOrgin[0];
			}
			list2 = (from pt in list2
			orderby pt.Z descending
			select pt).ToList<XYZ>();
			return list2[0];
		}

		private Element GetBoundingFloofOrRoof(Element mepElem, ViewPlan viewPlan)
		{
			List<Element> list = new List<Element>();
			foreach (Autodesk.Revit.DB.Document doc in this.m_lstDoc)
			{
				Element intersectFloors = this.GetIntersectFloors(doc, viewPlan, mepElem, BuiltInCategory.OST_Floors);
				if (intersectFloors != null)
				{
					list.Add(intersectFloors);
				}
				Element intersectFloors2 = this.GetIntersectFloors(doc, viewPlan, mepElem, BuiltInCategory.OST_Roofs);
				if (intersectFloors2 != null)
				{
					list.Add(intersectFloors2);
				}
			}
			if (list.Count > 0)
			{
				return list[0];
			}
			return null;
		}

		private Element GetIntersectFloors(Autodesk.Revit.DB.Document doc, ViewPlan viewPlan, Element mepElem, BuiltInCategory builtCategory)
		{
			try
			{
				BoundingBoxXYZ boundingBoxXYZ = mepElem.get_BoundingBox(viewPlan);
				Outline outline = new Outline(boundingBoxXYZ.Min.Subtract(XYZ.BasisZ), boundingBoxXYZ.Max.Subtract(XYZ.BasisZ));
				if (outline.IsEmpty)
				{
					return null;
				}
				FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
				BoundingBoxIntersectsFilter boundingBoxIntersectsFilter = new BoundingBoxIntersectsFilter(outline);
				List<Element> list = filteredElementCollector.OfCategory(builtCategory).WhereElementIsNotElementType().WherePasses(boundingBoxIntersectsFilter).ToList<Element>();
				if (list != null && list.Count > 0)
				{
					return list[0];
				}
			}
			catch (Exception)
			{
				return null;
			}
			return null;
		}

		private List<Document> m_lstDoc;
	}
}
